from flask import Blueprint, jsonify, request
from app.err_no import errno_no
from loguru import logger
import json
import traceback
from app.db import dbUpdateManage
from hashlib import md5

blueprint = Blueprint('upgrade_manage', __name__, url_prefix='/api/upgrade')

download_baseUrl = '/api/upgrade/v1/getFile/'

@blueprint.route('/v1/get_upgrade_apkVersion', methods=['POST'])
def get_upgrade_apkVersion():
    '''
    获取APP升级版本
    '''
    try:
        j_data = json.loads(request.data)
        diningNo = j_data.get('diningNo')
        stallNo = j_data.get('stallNo')
        deviceNo = j_data.get('device_no')
        softVersion = j_data.get('softVersion')
        if diningNo is None or len(diningNo) <= 0 \
            or stallNo is None or len(stallNo) <= 0 \
            or deviceNo is None or len(deviceNo) <= 0 \
            or softVersion is None or len(softVersion) <= 0:
            return jsonify(errno_no.ErrServerParam.data(None))

        state_, serverVersion, filename = dbUpdateManage.get_upgrade_apkVersion(
                                        diningNo, 
                                        stallNo, 
                                        softVersion, 
                                        deviceNo)
        if state_ is None:
            return jsonify(errno_no.ErrServerDocumentNotExist.data(None))

        # download_baseUrl = '/api/upgrade/v1/getFile/'
        if 'upgrade' == state_:
            res = {
                'taskId': 'upgrade', 
                'softVersion': serverVersion, 
                'packageUrl': download_baseUrl + filename
            }
        else:
            res = {'taskId': 'ok'}

        return jsonify(errno_no.OK.data(res))
    except Exception as e:
        logger.error(f'errMsg:{str(e)},traceback={traceback.format_exc()}')
        return jsonify(errno_no.ErrServerRuntime.data(None))


@blueprint.route('/v1/upload_apk', methods=['POST'])
def upload_apk():
    '''
    上传APP升级包
    '''
    try:
        file_data = request.files.get('file_data')
        file_md5 = request.form.get('file_md5').upper()
        version_desc = request.form.get('version_desc')
        if file_data is None \
            or file_md5 is None or len(file_md5) <= 0 \
            or version_desc is None:
            return jsonify(errno_no.ErrServerParam.data(None))

        # 获取文件名
        filename = file_data.filename
        # 后缀名不是apk 或者 文件名不是 xxx_xxx_xxx.apk格式的
        if filename.endswith('.apk') is False or filename.count('_') != 2:
            logger.error(f'apk包名称不符合规则xxx_xxx_xxx.apk: filename={filename}')
            return jsonify(errno_no.ErrServerParamValue.data(None))

        stream = file_data.read()
        file_md5_src = md5(stream).hexdigest().upper()
        if file_md5_src != file_md5:
            logger.error(f'apk包md5值不匹配, recv md5={file_md5}, server calculate md5={file_md5_src}')
            return jsonify(errno_no.ErrServerParamValue.data(None))
        
        version = filename.split("_")[1]
        if version.count('.') != 2:
            logger.error(f'apk包名称不符合规则xxx_x.x.x_xxx.apk: filename={filename}')
            return jsonify(errno_no.ErrServerParamValue.data(None))

        res = str(dbUpdateManage.save_file_to_mongo(stream, filename, version, version_desc))
        if res == '0':
            return jsonify(errno_no.ErrServerDocumentExist.data(None))

        return jsonify(errno_no.OK.data({'files_id': res}))
    except Exception as e:
        logger.error(f'errMsg:{str(e)},traceback={traceback.format_exc()}')
        return jsonify(errno_no.ErrServerRuntime.data(None))


# download_baseUrl = '/api/upgrade/v1/getFile/'
@blueprint.route('/v1/getFile/<path:filename>', methods=['GET'])
def getFile(filename):
    '''
    下载APP升级包
    '''
    try:
        if filename.endswith('.apk') is False or filename.count('_') != 2:
            logger.error(f'apk包名称不符合规则xxx_xxx_xxx.apk: filename={filename}')
            return jsonify(errno_no.ErrServerParamValue.data(None))

        res = dbUpdateManage.get_file_from_mongo(filename)
        if res is None:
            return jsonify(errno_no.ErrServerDocumentNotExist.data(res))

        return res
    except Exception as e:
        logger.error(f'errMsg:{str(e)},traceback={traceback.format_exc()}')
        return jsonify(errno_no.ErrServerRuntime.data(None))


@blueprint.route('/v1/get_upgradeapkList', methods=['POST'])
def get_upgradeapkList():
    '''
    获取所有APP升级包列表
    '''
    try:

        res = dbUpdateManage.getUpgradeapkList()
        return jsonify(errno_no.OK.data({'apkList': res}))
    except Exception as e:
        logger.error(f'errMsg:{str(e)},traceback={traceback.format_exc()}')
        return jsonify(errno_no.ErrServerRuntime.data(None))
